#ifndef ENCODER_H
#define ENCODER_H

#include "EncoderSettings.h"
#include "Matrix.h"
#include "BitStream.h"
#include "BlockList.h"
#include "parallelSettings.h"
#include "RLE.h"
#include "Normalization.h"
#include "DCT.h"
#include "Quantization.h"
#include "ME.h"

class Encoder
{
public:
    Encoder() {}
    Encoder(QuantizationMatrix* qm, bool rle, int width, int height,  int matrixColumnSize);
    Encoder (EncoderSettings &config, QuantizationMatrix* qm, int matrixColumnSize);
    ~Encoder();

    util::BitStreamWriter *encodePFrame(uint8_t* orig, uint8_t* buff, uint8_t* previousFrame, bool useCUDA = true);
	void compressPFrame(BlockList &sourceFrame, util::BitStreamWriter** bswArray, MADInfoContainer &MADInfo, int index);
    util::BitStreamWriter *encode(uint8_t* buff, bool useCUDA = true);
private:
    uint8_t* _previousFrame;
    bool _RLE;
    int _totalBlocks;
    int _width;
    int _height;
    BlockList _blockList;
    string _logFile;
    int _matrixColumnLength;
    int _matrixSize;
    int _columnSize;
    int _meRange;
	QuantizationMatrix* _quantizationMatrix;

	RLE* _rleModule;
	Normalization* _normModule;
	DCT* _dctModule;
	Quantization* _quantModule;
	ME* _meModule;
};

#endif // ENCODER_H
